﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.ComponentModel;
using TuyennvLibrary.ServerApi.Controllers;

namespace TuyennvLibrary.Reflection
{
    public class ExecuteClass:IExecuteClass
    {   
        public object RunMethod(string classApi, string[] DataContructor, string method, Dictionary<string, string> parameters)
        {
            Type myTypeObj;
            object myclass;
            MethodInfo myMethodInfo = null;
            try
            {
                myTypeObj = Type.GetType(classApi);
                if (DataContructor != null && DataContructor.Length > 0)
                {
                    myclass = Activator.CreateInstance(myTypeObj, DataContructor);
                }
                else
                {
                    myclass = Activator.CreateInstance(myTypeObj);
                }

            }
            catch (Exception)
            {
                return Code.errorClass();
            }
            //Khoi tao doi tuong cua class

            //Xac dinh method
            try
            {
                MethodInfo[] methods = myTypeObj.GetMethods();
                foreach (MethodInfo item in methods)
                {
                    if (item.Name == method && item.GetParameters().Length == parameters.Count)
                    {
                        myMethodInfo = item;
                        break;
                    }
                }
                if (myMethodInfo == null)
                    return Code.errorMethod();

            }
            catch (Exception)
            {

                return Code.errorMethod();
            }
            //Lay cac tham so cua method
            ParameterInfo[] MethodParameters = myMethodInfo.GetParameters();
            object[] objParameters = new object[parameters.Count];
            //Gan cac gia tri cho cac tham so tuong ung tu string
            foreach (ParameterInfo param in MethodParameters)
            {
                try
                {
                    TypeConverter typeConverter = TypeDescriptor.GetConverter(param.ParameterType);
                    string value = parameters[param.Name];
                    objParameters[param.Position] = typeConverter.ConvertFromString(value);
                }
                catch (Exception)
                {

                    return Code.errorParams();
                }
            }
            object data = myMethodInfo.Invoke(myclass, objParameters);
            return data;
        }
        public object RunMethod(string classApi, string method, Dictionary<string, string> parameters)
        {
            return RunMethod(classApi, new string[] { }, method, parameters);
        }
        public object RunMethod(string pathDll, string classApi, string method, Dictionary<string, string> parameters)
        {
            return RunMethod(pathDll, classApi, new string[] { }, method, parameters);
        }
        public object RunMethod(string pathDll, string classApi,string[] DataContructor, string method, Dictionary<string, string> parameters)
        {
            //Load 
            var dll = Assembly.LoadFile(pathDll);
            //var manager = new AssemblyReflectionManager();
            //manager.LoadAssembly(pathDll, "demodomain");
            //Xac dinh kieu cua class
            Type myTypeObj;
            object myclass;
            MethodInfo myMethodInfo = null;
            try
            {

                myTypeObj = dll.GetType(classApi);
                if (DataContructor != null && DataContructor.Length > 0)
                {
                    myclass = Activator.CreateInstance(myTypeObj, DataContructor);
                }
                else
                {
                    myclass = Activator.CreateInstance(myTypeObj);
                }

            }
            catch (Exception)
            {
                return Code.errorClass();
            }
            //Khoi tao doi tuong cua class

            //Xac dinh method
            try
            {
                MethodInfo[] methods = myTypeObj.GetMethods();
                foreach (MethodInfo item in methods)
                {
                    if (item.Name == method && item.GetParameters().Length == parameters.Count)
                    {
                        myMethodInfo = item;
                        break;
                    }
                }
                if (myMethodInfo == null)
                    return Code.errorMethod();

            }
            catch (Exception)
            {

                return Code.errorMethod();
            }
            //Lay cac tham so cua method
            ParameterInfo[] MethodParameters = myMethodInfo.GetParameters();
            object[] objParameters = new object[parameters.Count];
            //Gan cac gia tri cho cac tham so tuong ung tu string
            foreach (ParameterInfo param in MethodParameters)
            {
                try
                {
                    TypeConverter typeConverter = TypeDescriptor.GetConverter(param.ParameterType);
                    string value = parameters[param.Name];
                    objParameters[param.Position] = typeConverter.ConvertFromString(value);
                }
                catch (Exception)
                {

                    return Code.errorParams();
                }
            }

            object data = myMethodInfo.Invoke(myclass, objParameters);
            //manager.UnloadAssembly(pathDll);
            return data;
        }
        public object RunMethod(string pathDll,string strClass, string method, object[] parameters)
        {
            var dll = Assembly.LoadFile(pathDll);
            Type myTypeObj;
            object myclass;
            myTypeObj = dll.GetType(strClass);
            myclass = Activator.CreateInstance(myTypeObj);
            MethodInfo myMethodInfo = null;
            try
            {
                MethodInfo[] methods = myTypeObj.GetMethods();
                foreach (MethodInfo item in methods)
                {
                    if (item.Name == method && item.GetParameters().Length == parameters.Length)
                    {
                        myMethodInfo = item;
                        break;
                    }
                }
                if (myMethodInfo == null)
                    return Code.errorMethod();

            }
            catch (Exception)
            {

                return Code.errorMethod();
            }
            object data = myMethodInfo.Invoke(myclass, parameters);
            return data;
        }
        //public object GetObjectClass(string strClass)
        //{
        //    Type myTypeObj;
        //    object myclass;
        //    myTypeObj = Type.GetType(strClass);
        //    myclass = Activator.CreateInstance(myTypeObj);
            
        //}
    }
}
